﻿using System;
using System.ComponentModel;
using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Threading;

namespace CgdataBase
{
    public class PipeController
    {
        private static PipeController _instance;
        public static PipeController Instance => _instance ?? (_instance = new PipeController());

        private Prism.Events.IEventAggregator Aggregator => EventHelper.Aggregator;
        private BackgroundWorker worker;
        private string PipeName => Assembly.GetExecutingAssembly().GetName().Name + Assembly.GetExecutingAssembly().GetName().Version.ToString();

        public PipeController()
        {
            worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += Worker_DoWork;
        }

        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                try
                {
                    using (var pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.In))
                    {
                        pipeServer.WaitForConnection();
                        LogHelper.Info("Client connected.");
                        using (StreamReader sr = new StreamReader(pipeServer))
                        {
                            var text = sr.ReadLine();
                            Aggregator.GetEvent<ShowWindowEvent>().Publish();
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Warn(ex);
                }
            }
        }

        public void Start()
        {
            worker.RunWorkerAsync();
        }

        public void Stop()
        {
            worker.CancelAsync();
        }

        public void WakeUpServer()
        {
            try
            {
                using (var pipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.Out))
                {
                    pipeClient.Connect(100);
                    LogHelper.Info("Connected to pipe.");

                    using (StreamWriter sw = new StreamWriter(pipeClient))
                    {
                        sw.AutoFlush = true;
                        sw.WriteLine(DateTime.Now.ToString());
                        Thread.Sleep(100);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Warn(ex);
            }
        }
    }
}